package application

import (
	"fmt"
	"gitee.com/dh114007/wechat_token/config"
	"gitee.com/dh114007/wechat_token/core/httputils"
	"gitee.com/dh114007/wechat_token/core/middleware"
	"gitee.com/dh114007/wechat_token/driver"
	"gitee.com/dh114007/wechat_token/driver/cache"
	"github.com/gorilla/mux"
	"github.com/justinas/alice"
	"github.com/sirupsen/logrus"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

type App struct {
	Router     *mux.Router
	Logger     *logrus.Logger
	Middleware *middleware.Middleware
}

func NewApp() *App {
	return &App{}
}

func (a *App) Initialize() {
	logger := driver.LoggerInstance()
	a.Router = mux.NewRouter()
	a.Middleware = middleware.NewMiddleware(logger)
	a.Logger = logger
	httputils.Logger = logger

	a.initializeRoutes()
}

func (a *App) initializeRoutes() {
	m := alice.New(a.Middleware.CORSMiddleware, a.Middleware.SignMiddleware, a.Middleware.LoggingMiddleware, a.Middleware.RecoverMiddleware)
	a.Router.Handle("/token", m.ThenFunc(a.getAccessToken)).Methods("POST")
	a.Router.Handle("/ticket", m.ThenFunc(a.getJsApiTicket)).Methods("POST")
	a.Router.Handle("/jscode2session", m.ThenFunc(a.getJSCode2Session)).Methods("POST")
	a.Router.Handle("/secret", m.ThenFunc(a.getAppSecret)).Methods("POST")
}

func (a *App) Run(addr string) {
	cache.LoadLocal(config.Conf.Wechat.Store)
	errc := make(chan error)
	go func() {
		a.Logger.Printf("listen on addr %s\n", addr)
		errc <- http.ListenAndServe(addr, a.Router)
	}()
	// Capture interrupts.
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errc <- fmt.Errorf("%s", <-c)
	}()
	a.Logger.Printf("exit %s", <-errc)
	cache.StoreLocal(config.Conf.Wechat.Store)
}

